package com.ybear.ybutils.utils;

import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.Locale;
import java.util.regex.Pattern;

public class ObjUtils {
    /**
     * 数字缩写
     * @param num   数值          eg:10000
     * @return      缩写结果       eg:10K
     */
    public static String toNumberSize(double num) {
        return toShorthand( num, 1000, 1, "", "K", "M", "B", "T" );
    }

    /**
     * 容量缩写
     * @param num   数值          eg:10000
     * @return      缩写结果       eg:9.8KB
     */
    public static String toMemorySize(double num) {
        return toShorthand(
                num,
                1024,
                1,
                "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "BB", "NB", "DB"
        );
    }

    /**
     * 数量大小缩写
     * @param num               数值
     * @param span              数值之间的跨度。eg：数字为1000，硬盘容量为1024
     * @param decimalCount      保留小数数量
     * @param unit              所有跨度的单位值
     * @return                  结果
     */
    public static String toShorthand(double num, int span, int decimalCount, String... unit) {
        if( unit == null || unit.length == 0 ) return String.valueOf( num );
        if( num == 0 || span < 0 ) return num + unit[ 0 ];
        int i = (int) Math.floor( Math.log( num ) / Math.log( span ) );
        String result = String.format(
                Locale.getDefault(),
                "%." + decimalCount + "f",
                num / Math.floor( Math.pow( span, i ) )
        );
        String[] split = result.split( "\\." );
        result = split.length >= 2 && "0".equals( split[ 1 ] ) ? split[ 0 ] : result;
        return result + ( i >= unit.length ? "" : unit[ i ] );
    }

    /**
     * 是否存在中文字符
     * @param s     处理的字符串
     * @return      结果
     */
    public static boolean isChineseChar(String s) {
        return Pattern.compile("[\\u4e00-\\u9fa5]").matcher( s ).find();
    }

    /**
     * 是否为为英文字符
     * @param c     处理的字符
     * @return      结果
     */
    public static boolean isEnglishChar(char c) {
        return ( c >= 65 && c <= 90 ) || ( c >= 97 && c <= 122 );
    }

    /**
     * 是否为为数字字符
     * @param n     处理的字符
     * @return      结果
     */
    public static boolean isNumber(char n) { return n >= 48 && n <= 57 ; }

    /**
     是否为数字或字母混合
     @param s       处理的字符串
     @return        结果
     */
    public static boolean isEnglishOrNumber(String s) {
        if( TextUtils.isEmpty( s ) ) return false;
        for( int i = 0; i < s.length(); i++ ) {
            char chr = s.charAt( i );
            if( !isEnglishChar( chr ) && !isNumber( chr ) ) return false;
        }
        return true;
    }

    /**
     是否为数字与字母混合
     @param s       处理的字符串
     @return        结果
     */
    public static boolean isEnglishAndNumber(String s, int minEnglishCount, int minNumberCount) {
        if( TextUtils.isEmpty( s ) ) return false;
        int engCount = 0, numCount = 0;
        for( int i = 0; i < s.length(); i++ ) {
            char chr = s.charAt( i );
            if( isEnglishChar( chr ) ) engCount++;
            if( isNumber( chr ) ) numCount++;
        }
        return ( engCount >= minEnglishCount && numCount >= minNumberCount ) &&
                engCount + numCount == s.length();
    }
    public static boolean isEnglishAndNumber(String s) {
        return isEnglishAndNumber( s, 1, 1 );
    }

    @NonNull
    public static String parseString(Object obj) { return String.valueOf( obj ); }

    public static byte parseByte(Object obj) {
        try { return Byte.parseByte( parseString( obj ) ); }
        catch(NumberFormatException e) { e.printStackTrace(); }
        return 0;
    }

    public static short parseShort(Object obj) {
        try { return (short) parseInt( obj ); }
        catch(NumberFormatException e) { e.printStackTrace(); }
        return 0;
    }

    public static int parseInt(Object obj) {
        try { return (int)parseFloat( obj ); }
        catch(NumberFormatException e) { e.printStackTrace(); }
        return 0;
    }

    public static long parseLong(Object obj) {
        try { return (long)parseFloat( obj ); }
        catch(NumberFormatException e) { e.printStackTrace(); }
        return 0L;
    }

    public static float parseFloat(Object obj) {
        try { return Float.parseFloat( toNumber( obj ) ); }
        catch(NumberFormatException e) { e.printStackTrace(); }
        return 0F;
    }

    public static double parseDouble(Object obj) {
        try { return Double.parseDouble( toNumber( obj ) ); }
        catch(NumberFormatException e) { e.printStackTrace(); }
        return 0D;
    }

    @NonNull
    public static char[] parseChars(Object obj) {
        try { return parseString( obj ).toCharArray(); }
        catch(Exception e) { e.printStackTrace(); }
        return new char[ 0 ];
    }

    @Nullable
    public static Character parseChar(Object obj) {
        char[] cs = parseChars( obj );
        return cs.length == 0 ? null : cs[ 0 ];
    }

    public static boolean parseBoolean(Object obj) {
        String s = parseString( obj );
        return Boolean.parseBoolean( s ) || "1".equalsIgnoreCase( s );
    }

    private static String toNumber(Object obj) {
        String s = parseString( obj );
        if( TextUtils.isEmpty( s ) || "null".equals( s ) ) return "0";
        return s.replaceAll( "，", "" )
                .replaceAll( ",", "" )
                .trim();
    }
}